import java.util.*;

public class Question1 {

	static int n;
	static int m;

	// startPoint和finishPoint 保存开始和结束的坐标
	static int[] startPoint;
	static int[] finishPoint;

	// 保存输入数组
	static int[][] table;

	// 记忆化
	// tmp[x1][y1] 对应 solveProblem(x1, y1, x2, y2)
	static int[][] tmp;

	// 使用静态Scanner方便主函数和函数中调用
	static Scanner input = new Scanner(System.in);

	public static void main(String[] args) {

		// 输入数据
		getInput();

		// 输出数据
		// print();

		// 调用solveProblem函数,得到最终答案
		System.out.println(solveProblem(startPoint[0], startPoint[1], finishPoint[0], finishPoint[1]));
		input.close();
	}

	// x1 y1为开始的坐标 x2 y2为结束坐标
	// 使用了递归,动态规划,记忆化 的方式解决
	static int solveProblem(int x1, int y1, int x2, int y2) {

		// 如果开始坐标为结束坐标,即为终止条件
		if (x1 == x2 && y1 == y2) {
			return 0;
		}

		else {

			// 如果没有计算过solveProblem(x1, y1, x2, y2),则开始处理
			if (tmp[x1][y1] == 0) {
				// 保存移动后的结果
				// 取个极大值保证 Math.min(a, b)取到正确的值,而不是0
				int a = Integer.MAX_VALUE / 2;
				int b = Integer.MAX_VALUE / 2;

				// 下一步移动的坐标
				int tag = 0;

				// 首先给出状态转移方程,也就是
				// f(x1,y1,x2,y2)的值等于

				// 1
				// + (从该点 移动到 该点附近的点 [设为(a,b)] 的花销+再从(a,b)移动到(x2,y2)的花销)中的最小值

				// f(x1,y1,x2,y2)=1 + Min(
				// | table[x1][y1] - table[x1-1][y1] | + f(x1-1,y1,x2,y2),
				// | table[x1][y1] - table[x1+1][y1] | + f(x1+1,y1,x2,y2),
				// | table[x1][y1] - table[x1][y1-1] | + f(x1,y1-1,x2,y2),
				// | table[x1][y1] - table[x1][y1+1] | + f(x1,y1+1,x2,y2)
				// )

				// 但其实并不是4个方向都需要处理
				// 给出一个例子:
				// a b c
				// d e f
				// g h i

				// 当前坐标是(1,1),目的是(2,1)
				// 那么下一步就有4个方向可以走,上下左右
				// 但其实走 上左右 一定不如 下 ,也就是必须要走 [靠近目的点] 的路径
				// 而不是走 [远离目的点] 的路径
				// 因此不需要记录已经走过了哪些点,因为不可能走以前走过的点

				// 证明如下:
				// 从(1,1)移动到(2,1)的花销是1+|e-h|
				// 如果使用(1,1)->(1,2)->(2,2)->(2,1)的路径,花销是1+|e-f|+1+|f-i|+1+|h-i|

				// 比较一下1+|e-h| ?= 3+|e-f|+|f-i|+|h-i|
				// |e-i|<=|e-f|+|f-i|
				// |e-h|<=|e-i|+|i-h| 三角不等式
				// 所以 |e-h|-|i-h|<=|e-i|
				// 所以 |e-h|-|i-h|<=|e-f|+|f-i|
				// 所以 |e-h| <=|e-f|+|f-i|+|i-h|
				// 所以 1+|e-h| < 3+|e-f|+|f-i|+|h-i|
				// 证毕

				// 一般情况下,开始坐标和结束坐标的xy都不相同,因此 {走 [靠近目的点] 的路径} 一般是两个方向

				// 如果相同则不用x坐标移动
				if (x1 != x2) {
					// 判断x2在x1的左右
					// 如果x2>x1,那么x1的移动方向就为x1+1,反之亦然
					tag = x1 < x2 ? 1 : -1;

					// 得到 从该点到(a,b)的花销+再从(a,b)移动到(x2,y2)的花销
					a = Math.abs(table[x1][y1] - table[x1 + tag][y1]) + solveProblem(x1 + tag, y1, x2, y2);
				}

				if (y1 != y2) {
					tag = y1 < y2 ? 1 : -1;
					b = Math.abs(table[x1][y1] - table[x1][y1 + tag]) + solveProblem(x1, y1 + tag, x2, y2);
				}

				// 得到两种移动方向的花销最小值,+1便是最后结果
				tmp[x1][y1] = Math.min(a, b) + 1;
			}

			// 返回最终结果
			return tmp[x1][y1];
		}
	}

	// 输入数据
	static void getInput() {
		int i;
		int j;

		// 需要先说明的一点是,题目中的行列与日常语言中说的行列是刚好相反的
		// 例如题目给的测试样例:

		// 6 3
		// (1, 1) (6, 3)
		// 1 1 1 1 1 1
		// 1 1 1 1 1 1
		// 1 1 1 1 1 1

		// 在日常语言中往往说的是这是3*6的数组,3行6列
		// 同时坐标也是相反的,(6,3)指的是日常语言中的(3,6)第3行第6列

		n = input.nextInt();
		m = input.nextInt();
		input.nextLine();

		// 读取样例中的 (1, 1) (6, 3)
		String s = input.nextLine();

		// 给这些变量开辟内存空间
		table = new int[m][n];
		tmp = new int[m][n];
		startPoint = new int[2];
		finishPoint = new int[2];

		// 循环输入获得table
		for (i = 0; i < m; i++) {
			for (j = 0; j < n; j++) {
				table[i][j] = input.nextInt();
			}
		}

		// 将(1, 1) (6, 3)中的空格去除
		s = s.replace(" ", "");

		// 将(1,1)(6,3) 开始和结尾的括号去除
		s = s.substring(1, s.length() - 1);

		// 将1,1)(6,3 分割为"1,1","6,3" 也就是开始坐标和结束坐标的string形式
		String[] pointString = s.split("\\)\\(");

		// 举例,让i=0时
		// startPoint[0] = Integer.parseInt(pointString[0].split(",")[1 - 0]) - 1

		// pointString[0]也就是 1,1
		// pointString[0].split(",") 也就是 "1","1"

		// pointString[0].split(",")[1 - 0] 也就是 "1"
		// 这里使用1-0,也就是1-i而不用i的原因是上文说到的 [同时坐标也是相反的]
		// Integer.parseInt(pointString[0].split(",")[1 - 0]) 也就是 把string "1"转换为int 1

		// Integer.parseInt(pointString[0].split(",")[1 - 0]) - 1
		// 因为java中数组的开始的0,也就是语言中的第一行列是java中的第0行列

		// startPoint[0]就是开始坐标的x

		for (i = 0; i < 2; i++) {
			startPoint[i] = Integer.parseInt(pointString[0].split(",")[1 - i]) - 1;
			finishPoint[i] = Integer.parseInt(pointString[1].split(",")[1 - i]) - 1;
		}
	}

	static void print() {
		System.out.println();
		int i;
		int j;

		System.out.println(startPoint[0] + " " + startPoint[1]);
		System.out.println(finishPoint[0] + " " + finishPoint[1]);

		for (i = 0; i < m; i++) {
			for (j = 0; j < n; j++) {
				System.out.print(table[i][j] + " ");
			}
			System.out.println();
		}

	}
}